package com.ihr360.payroll.service.salarytask;

import com.ihr360.commons.request.Ihr360SearchBody;
import com.ihr360.entity.ApplicationApprovalEntity;
import com.ihr360.excel.vo.CustomSpreadSheetValidateResult;
import com.ihr360.excel.vo.ImportRequest;
import com.ihr360.excel.vo.SpreadSheetValidatorRequest;
import com.ihr360.payroll.entity.task.PayPeriodEntity;
import com.ihr360.payroll.entity.task.PayPeriodTermEntity;
import com.ihr360.payroll.model.dto.salary.plan.SalaryPlan;
import com.ihr360.payroll.model.dto.salary.task.period.ActivePayPeriod;
import com.ihr360.payroll.model.vo.SalaryDataEntity;
import com.ihr360.payroll.model.vo.SalaryFieldEntity;
import com.ihr360.payroll.response.PayrollApprovalResponse;
import com.ihr360.payroll.type.PeriodState;
import com.ihr360.shared.basicstaffinfo.dto.SyncedBasicStaffInfo;
import com.ihr360.tasklet.JobExecutionOverview;
import org.springframework.data.domain.Page;

import javax.servlet.ServletOutputStream;
import java.util.List;
import java.util.Map;

public interface SalaryTaskService {

    /**
     * 获取所有激活账期中的方案id列表
     *
     * @param companyId
     * @return
     */
    List<SalaryPlan> getActivePlanIds(String companyId, Long planId);

    /**
     * 获取所有激活账期中的考勤方案id列表
     *
     * @param companyId
     * @return
     */
    List<SalaryPlan> getActiveAttendancePlanIds(String companyId, Long attendancePlanId);

    /**
     * 获取所有激活账期中的工资表id列表
     *
     * @param companyId
     * @return
     */
    List<SalaryPlan> getActivePayrollConfigIds(String companyId, Long payrollConfigId);

    /**
     * 获取(当前用户可以访问的)核算列表
     *
     * @param companyId
     * @return
     */
    List<PayPeriodEntity> getPayPeriods(String companyId);

    /**
     * 获取指定账期的信息
     *
     * @param periodId
     * @return
     */
    PayPeriodEntity getPayPeriod(Long periodId);

    /**
     * 撤销还原账期数据（删除）
     *
     * @param payPeriodId
     * @return
     */
    void revoke(Long payPeriodId);

    /**
     * 按照薪资方案id获取新的账期数据
     *
     * @param companyId
     * @param salaryPlanId
     * @return
     */
    PayPeriodEntity getNewPayPeriod(String companyId, Long salaryPlanId);

    /**
     * 设置账期信息(包括批次相关信息,当批次信息发生变化后，会重新生成批次信息)
     *
     * @param payPeriod
     * @return
     */
    PayPeriodEntity setupPayPeriod(Long payperiodId,PayPeriodEntity payPeriod);

    /**
     * 获取一个账期批次基本数据
     *
     * @param payPeriodTermId
     * @return
     */
    PayPeriodTermEntity getPayPeriodTerm(Long payPeriodTermId);

    /**
     * 薪资方案账期添加员工
     *
     * @param periodId
     * @param staffIdList
     */
    void addStaff2PayPeriod(Long periodId, List<String> staffIdList);

    /**
     * 薪资方案账期删除员工
     *
     * @param periodId
     * @param staffIdList
     */
    void deleteStaff2PayPeriod(Long periodId, List<String> staffIdList);

    /**
     * 薪资账期中的员工数据重新拉取
     * note: 重新拉取数据之后，账期状态变为MODIFYING
     *
     * @param periodId
     */

    JobExecutionOverview launchData(Long periodId);

    /**
     * 首次核算薪资中的全部员工
     * note: 账期处于“确认员工”状态（STAFF_CHECKING），才需执行
     *
     * @param periodId
     */

//    JobExecutionOverview firstCalculate(Long periodId);

    /**
     * 重新核算账期
     *
     * @param periodId
     * @param staffIdList
     * @param reloadData
     */
    JobExecutionOverview reCalculate(Long periodId, List<String> staffIdList, boolean reloadData);

    /**
     * 开启新的事务对当前账期数据进行保存
     *
     * @param payPeriod
     */
    void saveDataInNewTransaction(ActivePayPeriod payPeriod);

    /**
     * 获取账期数据的header数据
     *
     * @param periodId
     * @return
     */
    Map<String, SalaryFieldEntity> getPayPeriodHeaderMap(Long periodId);

    /**
     * 获取账期数据的员工数据
     * note：以薪资方案中的员工为准，在StaffPayPeriodTermSalary中存在的员工则显示具体数据，不在该表中的数据则构造出假数据以供显示
     *
     * @param companyId
     * @param periodId
     * @param searchBody
     * @return
     */
    Page<SalaryDataEntity> getPayPeriodStaffDataCells(String companyId, Long periodId,
                                                      Ihr360SearchBody<SyncedBasicStaffInfo> searchBody);

    /**
     * 保存修改的薪资数据
     *
     * @param salaryDataEntities
     */
    void savePayPeriodSalaryData(Long termId, List<SalaryDataEntity> salaryDataEntities);

    /**
     * 选中的薪资字段模板下载
     *
     * @param payPeriodId
     * @param selectedFieldCodes
     * @param containsData
     * @param outputStream
     * @return
     */
    void downloadTemplateBySelectedFields(Long payPeriodId, List<String> selectedFieldCodes,
                                          boolean containsData, ServletOutputStream outputStream);


    /**
     * 导入员工台账数据
     *
     * @param payPeriodId
     * @param importRequest
     */
    void importExcel(Long payPeriodId, ImportRequest importRequest);

    /**
     * 校验数据
     *
     * @param payPeriodId
     * @param request
     * @return
     */
    CustomSpreadSheetValidateResult validateExcelData(Long payPeriodId, SpreadSheetValidatorRequest request);

    /**
     * 导出薪资数据
     *
     * @param payPeriodId
     * @param outputStream
     */
    void exportExcel(Long payPeriodId, ServletOutputStream outputStream);

    /**
     * 根据审批applicationId查询账期信息
     */
    List<PayrollApprovalResponse> queryApprovalPayPeriod(String companyId, List<String> applicationIdList);

    /**
     * 提请审批保存审批id，状态
     */
    void saveApprovalApplicationId(String companyId, ApplicationApprovalEntity applicationApprovalEntity, Long id);

    /**
     * 审批同步修改账期状态
     */
    void updateApprovalState(String companyId, String applicationId, PeriodState state);

    void closeActivePeriod(Long id, String companyId);

}